home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / dict / _bin_tree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  14.9 KB  |  636 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _bin_tree.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. //------------------------------------------------------------------------------
  17. //
  18. //  bin_tree: base class for all binary tree  types
  19. //
  20. //  leaf oriented & doubly linked 
  21. //
  22. //------------------------------------------------------------------------------
  23.  
  24. #include <LEDA/impl/bin_tree.h>
  25.  
  26.  
  27. bin_tree_node* bin_tree::lookup(GenPtr x) const
  28. { bin_tree_node* p = locate(x);
  29.   if (p && cmp(p->k,x) == 0) return p;
  30.   return 0;
  31. }
  32.  
  33. void  bin_tree::change_inf(bin_tree_node* p,GenPtr y) 
  34. { clear_inf(p->i);
  35.   copy_inf(y);
  36.   p->i = y; 
  37.  }
  38.  
  39.  
  40. //------------------------------------------------------------------------------
  41. // locate(x) : returns pointer to leave with successor or predessor key of x
  42. //------------------------------------------------------------------------------
  43.  
  44. bin_tree_node* bin_tree::locate(GenPtr x) const
  45.   if (count==0) return 0;
  46.   return  int_type() ? int_search(x) : search(x);
  47. }
  48.  
  49.  
  50. //------------------------------------------------------------------------------
  51. // locate_succ(x) : returns pointer to leave with minimal key >= x
  52. //             nil if tree empty
  53. //------------------------------------------------------------------------------
  54.  
  55. bin_tree_node* bin_tree::locate_succ(GenPtr x) const
  56. { if (count==0) return 0;
  57.   bin_tree_node* p =  int_type() ? int_search(x) : search(x);
  58.   return (cmp(x,p->k) > 0) ? succ(p) : p ;
  59.  }
  60.  
  61.  
  62.  
  63. //------------------------------------------------------------------------------
  64. // locate_pred(x) : returns pointer to leave with maximal key <= x
  65. //                  nil if tree empty
  66. //------------------------------------------------------------------------------
  67.  
  68. bin_tree_node* bin_tree::locate_pred(GenPtr x) const 
  69. { if (count==0) return 0;
  70.   bin_tree_node* p =  int_type() ? int_search(x) : search(x);
  71.   return (cmp(x,p->k) < 0) ? pred(p) : p ;
  72.  }
  73.  
  74.  
  75.  
  76. //------------------------------------------------------------------------------
  77. // search(x) : returns pointer to leave with minimal key >= x
  78. //------------------------------------------------------------------------------
  79.  
  80. bin_tree_node* bin_tree::search(GenPtr x) const
  81. {
  82.   bin_tree_node* p = root();
  83.  
  84.   while (p->is_node())
  85.        p = (cmp(x,p->k) <= 0) ? p->child[left] : p->child[right];
  86.  
  87.   return p;
  88.  }
  89.  
  90.  
  91.  
  92. //------------------------------------------------------------------------------
  93. // int_search : search for integer key 
  94. //------------------------------------------------------------------------------
  95.  
  96. bin_tree_node* bin_tree::int_search(GenPtr x) const
  97. {
  98.   bin_tree_node* p = root();
  99.  
  100.   while (p->is_node())
  101.        p = (long(x) <= long(p->k)) ? p->child[left] : p->child[right];
  102.  
  103.   return p;
  104.  }
  105.  
  106.  
  107.  
  108. //------------------------------------------------------------------------------
  109. // insert(x,y,ii):
  110. // inserts new leaf with key x and info y, sets info of new inner node to ii
  111. // returns pointer to the new leaf
  112. //------------------------------------------------------------------------------
  113.  
  114. bin_tree_node* bin_tree::insert( GenPtr x, GenPtr y, GenPtr ii)
  115. {  
  116.   // key x, inf y, iinf ii
  117.  
  118.   bin_tree_node* p;
  119.  
  120.    if (count==0)  // tree is empty 
  121.      { copy_key(x);
  122.        copy_inf(y);
  123.        p = new bin_tree_node(x,y,leaf_balance());
  124.        p->corr = &ROOT;
  125.        ROOT.i = ii;
  126.        min_ptr() = p;
  127.        root() = p;
  128.        p->parent = &ROOT;
  129.        p->child[right] = p;
  130.        p->child[left] = p;
  131.        count = 1;
  132.      }
  133.    else
  134.      { p = (int_type()) ? int_search(x) : search(x);
  135.        p = insert_at_item(p,x,y,ii);
  136.       }
  137.  
  138.    return p ;
  139.  }
  140.  
  141.  
  142.  
  143. bin_tree_node* bin_tree::insert_at_item(bin_tree_node* p, GenPtr x, GenPtr y, 
  144.                                                                     GenPtr ii)
  145. {
  146.  
  147.    bool insert_left;  //  true <==> insert new leaf q to the left of p
  148.  
  149.    copy_inf(y);
  150.                    
  151.    if ( int_type() )
  152.      { if ( long(x) == long(p->k) ) // x already stored in tree, overwrite info
  153.        { clear_inf(p->i);
  154.          p->i = y;
  155.          return p;
  156.         }
  157.        insert_left = (long(x) < long(p->k));
  158.       }
  159.    else
  160.       { int c = cmp(x,p->k);
  161.         if ( c == 0 )
  162.         { clear_inf(p->i);
  163.           p->i = y;
  164.           return p;
  165.          }
  166.         insert_left = (c < 0);
  167.         copy_key(x);
  168.        }
  169.  
  170.    int b = (count==1) ? root_balance() : node_balance();
  171.  
  172.    count++;
  173.  
  174.    bin_tree_node* q = new bin_tree_node(x,y,leaf_balance()); // new leaf
  175.    bin_tree_node* r = new bin_tree_node(0,0,b);              // new inner node
  176.    bin_tree_node* u = p->parent; 
  177.  
  178.    q->parent = r;
  179.    p->parent = r;
  180.    r->parent = u;
  181.    r->corr = nil;
  182.  
  183.  
  184.    if (p == u->child[left])
  185.       u->child[left] = r;
  186.    else
  187.       u->child[right] = r;
  188.  
  189.    // insertion of q, adjusting key & inf of corresponding inner nodes,
  190.    // double-chaining with neighbors, checking min pointer, ...
  191.  
  192.    if (insert_left) // insert q left of p
  193.       { r->k = x;
  194.         q->corr = r;
  195.         r->i = ii;
  196.         r->child[left] = q;
  197.         r->child[right]= p;
  198.         u = p->child[left];
  199.         q->child[left]  = u;
  200.         q->child[right] = p;
  201.         u->child[right] = q;
  202.         p->child[left]  = q;
  203.         if ( p == min_ptr() ) min_ptr() = q;     
  204.        }
  205.     else         // insert q right of p
  206.       { bin_tree_node* pc = p->corr; 
  207.         r->k = p->k;
  208.         r->i = pc->i;
  209.         pc->i = ii;
  210.         q->corr = pc;
  211.         p->corr = r;
  212.         r->child[left] = p;
  213.         r->child[right]= q;
  214.         u = p->child[right];
  215.         q->child[left]  = p;
  216.         q->child[right] = u;
  217.         u->child[left] = q;
  218.         p->child[right] = q;
  219.        }
  220.  
  221.     propagate_modification(1,r,p);
  222.     propagate_modification(2,r,q);
  223.  
  224.     if (r != root()) insert_rebal(r);
  225.  
  226.     return q;
  227.  
  228. }
  229.  
  230.  
  231.  
  232. //------------------------------------------------------------------------------
  233. // del(x) 
  234. // removes leaf with key x from the tree
  235. // overwrites possible copy of x in an inner node (if key type is not integer)
  236. //------------------------------------------------------------------------------
  237.  
  238. void bin_tree::del(GenPtr x)
  239. {
  240.   bin_tree_item v;
  241.  
  242.   if (count == 0) return;  // tree is empty
  243.  
  244.   if ( int_type() )
  245.     { v = int_search(x);
  246.       if (long(v->k) == long(x)) del_item(v);
  247.      }
  248.   else
  249.     { v = search(x);
  250.       if ( cmp(v->k,x) == 0 ) del_item(v);
  251.      }
  252.  
  253.  
  254.  }
  255.  
  256.  
  257. void bin_tree::del_item(bin_tree_item v)
  258. {
  259.   bin_tree_item w;
  260.   bin_tree_item p = v->parent;
  261.   bin_tree_item u = v->corr;
  262.  
  263.   clear_key(v->k);
  264.   clear_inf(v->i);
  265.  
  266.   // overwrite copy of key in corresponding inner node u by its predecessor,
  267.   // but keep its information (not necessary in the case that v is a left child)
  268.  
  269.   if (v != p->child[left]) 
  270.   { bin_tree_node* pred =  v->child[left];
  271.     u->k = pred->k;
  272.     clear_iinf(pred->corr->i);
  273.     pred->corr = u;
  274.   }
  275.   else
  276.     clear_iinf(u->i);
  277.  
  278.   count--;
  279.  
  280.   if (count == 0)      // tree is now empty
  281.   { root() = min_ptr() = nil;
  282.     delete v;
  283.     return;
  284.    } 
  285.  
  286.  
  287.   bin_tree_node* pred = v->child[left];
  288.   bin_tree_node* succ = v->child[right];
  289.  
  290.   // link neighbors
  291.   pred->child[right] = succ; 
  292.   succ->child[left] = pred;
  293.  
  294.   // adjust min pointer
  295.   if ( v == min_ptr() ) min_ptr() = succ;
  296.  
  297.  
  298.   // replace p by sibling w of v
  299.  
  300.   u = p->parent;
  301.   w = p->child[left];
  302.   if (v == w) w =  p->child[right];
  303.   w->parent = u;
  304.   if (p == u->child[left])
  305.      u->child[left] = w;
  306.   else
  307.      u->child[right] = w;
  308.  
  309.                                 //     u             u            u
  310.                                 //     |             |            |
  311.                                 //     p     or      p    --->    w
  312.                                 //    / \           / \
  313.                                 //   v   w         w   v
  314.  
  315.   propagate_modification(3,u,w);
  316.  
  317.   // rebalance tree, if necessary
  318.  
  319.   if (w != root()) del_rebal(w,p);
  320.  
  321.   delete v;
  322.   delete p;
  323.  
  324. }
  325.  
  326.  
  327. //------------------------------------------------------------------
  328. // concatenate
  329. //------------------------------------------------------------------
  330.  
  331. bin_tree& bin_tree::conc(bin_tree&) 
  332. { error_handler(1,"sorry, bin_tree::conc not implemented"); 
  333.   return *this;
  334.  }
  335.  
  336. //------------------------------------------------------------------
  337. // split at item
  338. //------------------------------------------------------------------
  339.  
  340. void bin_tree::split_at_item(bin_tree_node*,bin_tree&,bin_tree&) 
  341. { error_handler(1,"sorry, bin_tree::split_at_item not implemented"); }
  342.  
  343.  
  344. //------------------------------------------------------------------
  345. // reverse items
  346. //------------------------------------------------------------------
  347.  
  348. void bin_tree::reverse_items(bin_tree_node* v, bin_tree_node* w)
  349. {
  350.   bin_tree_node* l = v;
  351.   bin_tree_node* r = w;
  352.  
  353.   while (l != r && r->child[right] != l) 
  354.   {
  355.     bin_tree_node* pl = l->parent;
  356.     bin_tree_node* pr = r->parent;
  357.     bin_tree_node* cl = l->corr;
  358.     bin_tree_node* cr = r->corr;
  359.  
  360.  
  361.     // exchange l and r
  362.  
  363.    if (pl == pr)
  364.      { pl->child[left] = r;
  365.        pl->child[right] = l;
  366.       }
  367.    else
  368.      { if (l == pl->child[left])
  369.           pl->child[left] = r;
  370.        else
  371.           pl->child[right] = r;
  372.     
  373.        r->parent = pl;
  374.     
  375.        if (r == pr->child[left])
  376.           pr->child[left] = l;
  377.        else
  378.           pr->child[right] = l;
  379.     
  380.        l->parent = pr;
  381.       }
  382.   
  383.  
  384.    // update corresponding inner nodes
  385.  
  386.    l->corr = cr;
  387.    cr->k = l->k;
  388.  
  389.    r->corr = cl;
  390.    cl->k = r->k;
  391.  
  392.    l = l->child[right]; 
  393.    r = r->child[left];
  394.  
  395.   }
  396.  
  397.   // reverse chaining of leaves v...w
  398.  
  399.   if (count > 2)
  400.   { l = v->child[left];
  401.     r = w->child[right];
  402.   
  403.     r->child[left] = v;
  404.   
  405.     bin_tree_node* p = v; 
  406.   
  407.     while(p != w)
  408.     { bin_tree_node* q = p->child[right];
  409.       p->child[left] = q;
  410.       p = q;
  411.      }
  412.   
  413.     w->child[left] = l;
  414.   
  415.     p = r;
  416.   
  417.     while ( p != l )
  418.     { bin_tree_node* q = p->child[left];
  419.       q->child[right] = p;
  420.       p = q;
  421.      }
  422.    }
  423.   
  424.  
  425.   // adjust min pointer
  426.   
  427.   if (v == min_ptr()) min_ptr() = w;
  428.  
  429.  }
  430.  
  431.  
  432. //------------------------------------------------------------------
  433. // operator=
  434. //------------------------------------------------------------------
  435.  
  436. bin_tree& bin_tree::operator=(const bin_tree& t)
  437. {
  438.    if (this == &t) return *this;
  439.  
  440.    clear();
  441.  
  442.    if ( t.root() )   
  443.    { bin_tree_node* pre = 0;
  444.      root() = t.copy_tree(t.root(),pre);
  445.      root()->parent = &ROOT;
  446.      pre->corr = &ROOT;
  447.      ROOT.i = t.ROOT.i;
  448.      min_ptr() = root();
  449.      while (min_ptr()->child[left]) min_ptr() = min_ptr()->child[left];
  450.      min_ptr()->child[left] = pre;
  451.      pre->child[right] = min_ptr();
  452.      count = t.count;
  453.    }
  454.  
  455.    return *this; 
  456. }
  457.  
  458. //------------------------------------------------------------------
  459. // copy constructor
  460. //------------------------------------------------------------------
  461.  
  462.   bin_tree::bin_tree(const bin_tree& t)
  463.   { root()  = min_ptr() = 0 ;
  464.     count = t.count; 
  465.     if ( t.root() ) 
  466.     { bin_tree_node* pre = 0;
  467.       root() = t.copy_tree(t.root(),pre);
  468.       min_ptr() = root();
  469.       root()->parent = &ROOT;
  470.       while (min_ptr()->child[left]) min_ptr() = min_ptr()->child[left];
  471.       min_ptr()->child[left] = pre;
  472.       pre->child[right] = min_ptr();
  473.      }
  474.   }
  475.  
  476.  
  477. //------------------------------------------------------------------
  478. // copy_tree(p) makes a copy of tree with root p and returns a pointer to the
  479. // root of the copy. pre is last created leaf ( leaves are created from left 
  480. // to right).
  481. //------------------------------------------------------------------
  482.  
  483. bin_tree_node* bin_tree::copy_tree( bin_tree_node* p, bin_tree_item& pre) const
  484. {
  485.   bin_tree_node* q = new bin_tree_node(p);  // q = p
  486.  
  487.   if ( p->is_node() )  // internal node: copy subtrees 
  488.   {
  489.     q->child[left] = copy_tree(p->child[left],pre);
  490.     pre->corr = q;
  491.     q->child[right] = copy_tree(p->child[right],pre);
  492.     q->child[left]->parent = q;
  493.     q->child[right]->parent = q;
  494.   }
  495.   else   //leaf: chaining with last created leaf "pre"
  496.   {
  497.     copy_key(q->k);
  498.     copy_inf(q->i);
  499.  
  500.     if (pre) pre->child[right] = q; 
  501.     q->child[left] = pre;
  502.     pre = q;
  503.  
  504.    }
  505.  
  506.   return q;
  507. }
  508.  
  509. //------------------------------------------------------------------
  510. // clear
  511. //------------------------------------------------------------------
  512.  
  513. void bin_tree::clear() 
  514. {
  515.    if ( root() )
  516.    { del_tree(root());
  517.      root() = min_ptr() = 0;
  518.      count = 0;
  519.    }
  520. }
  521.  
  522. //------------------------------------------------------------------
  523. // del_tree(p) : deletes subtree rooted at node p
  524. //------------------------------------------------------------------
  525.  
  526. void bin_tree::del_tree(bin_tree_node* p)
  527. {
  528.   if ( p->is_node() )
  529.   { del_tree(p->child[left]);
  530.     del_tree(p->child[right]);
  531.    }
  532.   else
  533.   { clear_key(p->k);
  534.     clear_inf(p->i);
  535.     clear_iinf(p->corr->i);
  536.    }
  537.  
  538.   delete p;
  539. }
  540.  
  541.  
  542.  
  543.  
  544. //----------------------------------------------------------------------------
  545. // printing and drawing trees
  546. //----------------------------------------------------------------------------
  547.  
  548. void bin_tree::print() const
  549.   cout << endl;
  550.   cout << "size = " << size() << endl;
  551.  
  552.   if ( root() ) print_tree(root(),1);
  553.  
  554.   register bin_tree_node* q = max() ;
  555.  
  556.   if( q ) {
  557.     newline; 
  558.     print_inf( inf(q) ) ;
  559.  
  560.     while( (q=pred(q)) ) { 
  561.       print_inf( inf(q->corr) ) ;
  562.       print_inf( inf(q) ) ;
  563.     }
  564.   }
  565.   newline;
  566. }
  567.  
  568.  
  569. void bin_tree::print_tree(bin_tree_node* p,int h) const
  570. {  
  571.   if ( p->is_node() ) print_tree(p->child[right],h+1);
  572.  
  573.  for( int j=1; j <= h ; j++ ) cout << "     ";
  574.  
  575.  print_key(key(p));
  576.  cout << " (" << p->get_bal() <<")";
  577.  
  578.  if ( p->is_leaf() )
  579.  { cout << "[" << int(p) << "] ";  
  580.    cout << " succ[" << int(p->child[right]) << "] ";  
  581.    print_key(key(p->child[right]));
  582.    cout << " pred[" << int(p->child[left]) << "] "; 
  583.    print_key(key(p->child[left]));
  584.    newline;
  585.  }
  586.  else cout << "\n";
  587.  
  588.  if ( p->is_node() ) print_tree(p->child[left],h+1);
  589. }
  590.  
  591.         
  592.  
  593. void bin_tree::draw(DRAW_BIN_NODE_FCT draw_node,
  594.                     DRAW_BIN_NODE_FCT draw_leaf,
  595.                     DRAW_BIN_EDGE_FCT draw_edge, 
  596.                     double x1, double x2, double y, double ydist)
  597.   // draw a picture of the tree using the functions
  598.   // draw_node(x,y,k,b)   draws node with key k and balance b at (x,y)
  599.   // draw_leaf(x,y,k,b)   draws leaf with key k and balance b at (x,y)
  600.   // draw_edge(x,y,x',y') draws an edge from (x,y) to (x',y')
  601.  
  602.   draw(draw_node,draw_leaf,draw_edge,root(),x1,x2,y,ydist,0); 
  603.  }
  604.  
  605.  
  606.  
  607. void bin_tree::draw(DRAW_BIN_NODE_FCT draw_node,
  608.                     DRAW_BIN_NODE_FCT draw_leaf,
  609.                     DRAW_BIN_EDGE_FCT draw_edge, 
  610.                     bin_tree_node* r, 
  611.                     double x1, double x2, double y, 
  612.                     double ydist, double last_x)
  613.   // draw subtree rooted at r
  614.  
  615.   double x = (x1+x2)/2;
  616.  
  617.   if (r==nil) return;
  618.  
  619.   if (last_x != 0) draw_edge(last_x,y+ydist,x,y);
  620.  
  621.   if (r->is_node()) 
  622.      { draw_node(x,y,r->k,r->get_bal());
  623.        draw(draw_node,draw_leaf,draw_edge, r->child[0],x1,x,y-ydist,ydist,x);
  624.        draw(draw_node,draw_leaf,draw_edge, r->child[1],x,x2,y-ydist,ydist,x);
  625.       }
  626.   else
  627.      draw_leaf(x,y,r->k,r->get_bal());
  628. }
  629.  
  630.  
  631.